package com.ecarx.module_log.controller;


import android.content.Context;
import android.os.CountDownTimer;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;

import com.ecarx.library_base.base_util.GsonUtils;
import com.ecarx.library_base.base_util.SPUtil;
import com.ecarx.library_base.base_util.ThreadUtils;
import com.ecarx.library_base.scoket.SocketManager;
import com.ecarx.library_base.scoket.callback.MsgCallback;
import com.ecarx.library_base.scoket.callback.Packetlistener;
import com.ecarx.library_base.scoket.model.SocketRequest;
import com.ecarx.library_base.scoket.model.SocketResponse;
import com.ecarx.library_base.usb.UDiskDevice;
import com.ecarx.module_log.LogControlViewCallback;

import com.ecarx.module_log.bean.CleanLogReq;
import com.ecarx.module_log.bean.ControlRecordLogReq;
import com.ecarx.module_log.bean.QueryLogStatusBean;
import com.ecarx.module_log.bean.SetLogStatusResponse;
import com.ecarx.module_log.logexport.controller.LogExportController;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.stream.StreamSupport;

public class LogManagerController {

    public static final String TAG = "LogManagerController";
    private static final String PROPERTY_LOG_CLEAN_ENABLE = "persist.service.logclean.enable";
    private static final String PROPERTY_MCU_LOG_CLEAN_ENABLE = "persist.service.mculogclean.enable";
    private static final String PROPERTY_LOG_AP_ENABLE = "persist.service.logcat.enable";
    private static final String PROPERTY_TCPDUMP_ENABLE = "persist.service.tcpdump.enable";
    private static final String PROPERTY_BTLOG_ENABLE = "persist.service.btlog.enable";

    private static final String LOG_PATH_AP = "/data/log";
    private static final String MCU_LOG_PATH_AP = "/data/McuLog";
    private static final String LOG_PATH_NET = "/data/tcpdump";
    private static final String LOG_PATH_ANR = "/data/anr";
    private static final String LOG_PATH_TOMSTONES = "/data/tombstones";
    private static final String LEVEL_KEY = "persist.service.engineerMode_loglevel";
    private static final int QUERY_OSCONTROL_STATUS_MSGID = 4001;
    private static final int SET_OSCONTROL_STATUS_MSGID = 4002;
    private CountDownTimer mLogCleanCountDownTimer;
    private boolean reOpenApLog, reOpenBtLog, reOpenNetLog;
    private final LogExportController logExportControl = new LogExportController();
    private LogControlViewCallback mCallback;
    private Context mContext;

    private static final String SAVE_OPEN_LOG_TYPE_KEY = "mOpenLogType";
    private static final String SAVE_CLEAR_LOG_TYPE_KEY = "mClearLogType";
    private static final String SAVE_EXPORT_LOG_TYPE_KEY = "mExportLogType";
    private static final String UXOS_TYPE = "UX_OS";

    private static final String MCU_TYPE = "MCU";
    private String mCurLogControlOSType, mCurLogCleanOSType, mCurLogExportOSType;

    private boolean mIsTcpLogOpen, mIsBlueToothLogOpen;
    private String mCurLogControlOSLevel = "V";
    private int mCurControlOSStatus = 0;
    public String[] level_array = {};
    public static final String[] UXOS_LEVEL_ARRAY = {"V", "D", "I", "W", "E", "F", "S"};
    public static final String[] GUEST_LEVEL_ARRAY = {"D", "I", "W", "E", "F"};
    public static final String[] LOGTYPES = {UXOS_TYPE, SocketManager.ServerOS.Cluster_OS.toString(),
//            SocketManager.ServerOS.Game_OS.toString(),
            SocketManager.ServerOS.Hypervisor_OS.toString()};
    public static final String[] CLEAN_LOGTYPES = {UXOS_TYPE, MCU_TYPE, SocketManager.ServerOS.Cluster_OS.toString(), SocketManager.ServerOS.Hypervisor_OS.toString()};

    public LogManagerController(LogControlViewCallback controlViewCallback, Context context) {
        this.mCallback = controlViewCallback;
        this.mContext = context;
    }

    private MsgCallback mMsgCallback = new MsgCallback() {
        @Override
        public void onConnected() {
            Log.d(TAG, "onConnected: ");
            queryOSControlStatus();
        }

        @Override
        public void onDisConnected() {
            Log.d(TAG, "onDisConnected: ");

        }

        @Override
        public void onConnectFail() {
            if (!isUXOSType(mCurLogControlOSType)) {
                SocketManager.get().disConnectServer(SocketManager.ServerOS.valueOf(mCurLogControlOSType));
            }
            Log.d(TAG, "onConnectFail: ");
            setSocketDataFail();
        }

        @Override
        public void onReceiver(int msgId, String msg) {
            Log.d(TAG, "onReceiver: msgId=" + msgId + "----msg=" + msg);
        }

        @Override
        public void onFail(String reason) {
            Log.d(TAG, "onFail: " + reason);
        }
    };

    /**
     * 初始化日志导出view和监听事件
     */
    public void init() {
        initGuestOsLogType();
        initLogExport();
        initBtAndTcpRecordState();
        level_array = GUEST_LEVEL_ARRAY;
        if (isUXOSType(mCurLogControlOSType)) {
            level_array = UXOS_LEVEL_ARRAY;
            mCurControlOSStatus = SystemProperties.getInt(PROPERTY_LOG_AP_ENABLE, 0);
            mCallback.setUXOSLevelDataAndIndex(getRecordLevelPosition());
            mCallback.changApRecordState(isApRecording());
        } else {
            mCallback.setGuestOSLevelData(getRecordLevelPosition());
            connectSocket();
        }
        if (mCurLogCleanOSType.equals(CLEAN_LOGTYPES[2]) || mCurLogCleanOSType.equals(CLEAN_LOGTYPES[3])) {
            if (!mCurLogCleanOSType.equals(mCurLogControlOSType)) {
                if (!SocketManager.get().isConnected(SocketManager.ServerOS.valueOf(mCurLogCleanOSType))) {
                    SocketManager.get().connectServer(SocketManager.ServerOS.valueOf(mCurLogCleanOSType));
                }
            }
        }

    }

    /**
     * 初始化日志清除，日志导出，日志开关日志系统类型
     */
    private void initGuestOsLogType() {
        mCurLogControlOSType = (String) SPUtil.get(mContext, SAVE_OPEN_LOG_TYPE_KEY, LOGTYPES[0]);
        mCallback.setControllerOSIndex(getLogTypePosition(mCurLogControlOSType));
        mCurLogCleanOSType = (String) SPUtil.get(mContext, SAVE_CLEAR_LOG_TYPE_KEY, CLEAN_LOGTYPES[0]);
        mCallback.setLogCleanOSIndex(getCleanLogTypePosition(mCurLogCleanOSType));
        mCurLogExportOSType = (String) SPUtil.get(mContext, SAVE_EXPORT_LOG_TYPE_KEY, LOGTYPES[0]);
        mCallback.setLogOutOSIndex(getLogTypePosition(mCurLogExportOSType));
    }

    /**
     * 与当前日志系统类型建立socket连接
     */
    private void connectSocket() {
        Log.d(TAG, "connectSocket: ");
        if (!SocketManager.get().isConnected(SocketManager.ServerOS.valueOf(mCurLogControlOSType))) {
            SocketManager.get().connectServer(SocketManager.ServerOS.valueOf(mCurLogControlOSType));
            SocketManager.get().registerCallback(SocketManager.ServerOS.valueOf(mCurLogControlOSType), mMsgCallback);
        } else {
            queryOSControlStatus();
        }
    }

    /**
     * 查询当前日志系统类型日志状态和日志等级
     */
    private void queryOSControlStatus() {
        String request = getRequestString(QUERY_OSCONTROL_STATUS_MSGID, -1, -1);
        SocketManager.get().sendRequest(SocketManager.ServerOS.valueOf(mCurLogControlOSType), request, new Packetlistener() {
            @Override
            public void onTimeout() {
                Log.d(TAG, "queryOSControlStatus onTimeout: ");
                setSocketDataFail();
            }

            @Override
            public void onSuccess(int msgId, String response) {

                queryOSStatusResult(msgId, response);

            }

            @Override
            public void onFail(int code, String reason) {
                Log.d(TAG, "queryOSControlStatus onFail:code= " + code + "---reason" + reason);
                setSocketDataFail();
            }
        });
    }

    private void cleanGuestOsLog() {
        SocketManager.ServerOS serverOS = SocketManager.ServerOS.valueOf(mCurLogCleanOSType);
        if (!SocketManager.get().isConnected(serverOS)) {
            SocketManager.get().connectServer(serverOS);
        }
        CleanLogReq req = new CleanLogReq(1);
        String request = GsonUtils.toJson(new SocketRequest(SET_OSCONTROL_STATUS_MSGID, System.currentTimeMillis(), "0", req));
        SocketManager.get().sendRequest(SocketManager.ServerOS.valueOf(mCurLogCleanOSType), request, new Packetlistener() {
            @Override
            public void onTimeout() {
                Log.d(TAG, "cleanGuestOSRecording onTimeout: ");
                mCallback.cleanGuestLogFinish(false);
            }

            @Override
            public void onSuccess(int msgId, String response) {
                Log.d(TAG, "cleanGuestOSRecording onSuccess: msgId=" + msgId + "----response=" + response);
                SocketResponse socketResponse = GsonUtils.fromJson(response, SocketResponse.class);
                if (socketResponse.getMsgId() == SET_OSCONTROL_STATUS_MSGID) {
                    mCallback.cleanGuestLogFinish(true);
                }

            }

            @Override
            public void onFail(int code, String reason) {
                Log.d(TAG, "cleanGuestOSRecording onFail: code=" + code + "----reason=" + reason);
                mCallback.cleanGuestLogFinish(false);
            }
        });
    }


    private void queryOSStatusResult(int msgId, String response) {
        Log.d(TAG, "queryOSControlStatus onSuccess: msgId=" + msgId + "response=" + response);
        SocketResponse socketResponse = GsonUtils.fromJson(response, SocketResponse.class);
        if (socketResponse.getMsgId() == QUERY_OSCONTROL_STATUS_MSGID) {
            QueryLogStatusBean bean = socketResponse.dataToJsonObj(QueryLogStatusBean.class);
            Log.d(TAG, "getLogStatusBean: bean = " + bean + ",,logType= " + mCurLogControlOSType);
            SPUtil.put(mContext, mCurLogControlOSType, bean.getStatus());
            SPUtil.put(mContext, mCurLogControlOSType + "LEVEL", level_array[bean.getLogLevel()]);
            mCurLogControlOSLevel = level_array[bean.getLogLevel()];
            mCurControlOSStatus = bean.getStatus();
            ThreadUtils.runOnUiThread(() -> {
                mCallback.setGuestOSLevelData(getRecordLevelPosition());
                mCallback.changApRecordState(mCurControlOSStatus == 1);
            });
        }
    }

    /**
     * 设置日志开关和日志等级状态
     *
     * @param open     1：开  0：关
     * @param logLevel
     */
    private void setGuestOSRecording(int open, int logLevel) {
        String request = getRequestString(SET_OSCONTROL_STATUS_MSGID, open, logLevel);
        SocketManager.get().sendRequest(SocketManager.ServerOS.valueOf(mCurLogControlOSType), request, new Packetlistener() {
            @Override
            public void onTimeout() {
                Log.d(TAG, "setGuestOSRecording onTimeout: ");
                setSocketDataFail();
            }

            @Override
            public void onSuccess(int msgId, String response) {
                Log.d(TAG, "setGuestOSRecording onSuccess: msgId=" + msgId + "----response=" + response);
                SocketResponse socketResponse = GsonUtils.fromJson(response, SocketResponse.class);
                if (socketResponse.getMsgId() == SET_OSCONTROL_STATUS_MSGID) {
                    SetLogStatusResponse bean = socketResponse.dataToJsonObj(SetLogStatusResponse.class);
                    Log.d(TAG, "getLogStatusBean: bean = " + bean + ",,logType= " + mCurLogControlOSType);
                    SPUtil.put(mContext, mCurLogControlOSType, bean.getOpen());
                    SPUtil.put(mContext, mCurLogControlOSType + "LEVEL", level_array[bean.getLogLevel()]);
                    mCurLogControlOSLevel = level_array[bean.getLogLevel()];
                    mCurControlOSStatus = bean.getOpen();
                    ThreadUtils.runOnUiThread(() -> {
                        mCallback.setGuestOSLevelData(getRecordLevelPosition());
                        mCallback.changApRecordState(mCurControlOSStatus == 1);
                    });
                }

            }

            @Override
            public void onFail(int code, String reason) {
                Log.d(TAG, "setGuestOSRecording onFail: code=" + code + "----reason=" + reason);
                setSocketDataFail();
            }
        });
    }

    private String getRequestString(int msgId, int open, int logLevel) {
        ControlRecordLogReq req = null;
        if (open >= 0) {
            req = new ControlRecordLogReq(open, logLevel);
        }
        String request = GsonUtils.toJson(new SocketRequest(msgId, System.currentTimeMillis(), "0", req));
        return request;
    }


    /**
     * 初始化蓝牙和tcp日志状态
     */
    private void initBtAndTcpRecordState() {
        mIsTcpLogOpen = false;
        mIsBlueToothLogOpen = false;
        if (SystemProperties.get(PROPERTY_TCPDUMP_ENABLE, "0").equals("1")) {
            mIsTcpLogOpen = true;
        }
        if (SystemProperties.get(PROPERTY_BTLOG_ENABLE, "0").equals("1")) {
            mIsBlueToothLogOpen = false;
        }
    }

    /**
     * 初始化日志导出
     */
    public void initLogExport() {
        logExportControl.init(new LogExportController.LogExportCallback() {
            @Override
            public void onCopyFinish(boolean isSuccess, String strings) {
                mCallback.finishLogExport(isSuccess);
            }

            @Override
            public void onUsbChanged(boolean isAdd, List<UDiskDevice> uDiskDeviceList) {
                mCallback.onUsbChanged(isAdd, uDiskDeviceList);
            }
        });
    }

    /**
     * 返回当前日志类型是否是开启的
     *
     * @return true 开启 false 关闭
     */
    public boolean isApRecording() {
        return mCurControlOSStatus == 1;
    }

    /**
     * 设置当前日志系统类型开关
     *
     * @param apRecoding true 开启 false 关闭
     */
    public void setCurOSRecording(boolean apRecoding) {
        if (isUXOSType(mCurLogControlOSType)) {
            mCurControlOSStatus = apRecoding ? 1 : 0;
            SystemProperties.set(PROPERTY_LOG_AP_ENABLE, mCurControlOSStatus + "");
            mCallback.setUXOSLevelDataAndIndex(getRecordLevelPosition());
            mCallback.changApRecordState(apRecoding);
        } else if (!isCurLogControlSocketConnect()) {
            setSocketDataFail();
        } else {
            int logLevelIndex = Arrays.asList(level_array).indexOf(mCurLogControlOSLevel);
            setGuestOSRecording(apRecoding ? 1 : 0, logLevelIndex);
        }
    }


    /**
     * 当前日志类型是否已经建立socket连接
     *
     * @return true 连接上 false 未连接
     */
    private boolean isCurLogControlSocketConnect() {
        return SocketManager.get().isConnected(SocketManager.ServerOS.valueOf(mCurLogControlOSType));
    }


    public boolean isBtRecording() {
        return mIsBlueToothLogOpen;
    }

    /**
     * 设置蓝牙日志开启
     *
     * @param btRecording true 开启  false 关闭
     */
    public void setBtRecording(boolean btRecording) {
        SystemProperties.set(PROPERTY_BTLOG_ENABLE, btRecording ? "1" : "0");
        mIsBlueToothLogOpen = btRecording;
    }

    public boolean isNetRecording() {
        return mIsTcpLogOpen;
    }

    /**
     * 设置tcp日志开启
     *
     * @param netRecording true 开启 false 关闭
     */
    public void setNetRecording(boolean netRecording) {
        SystemProperties.set(PROPERTY_TCPDUMP_ENABLE, netRecording ? "1" : "0");
        mIsTcpLogOpen = netRecording;
    }


    /**
     * 日志导出
     */
    public void logExport(UDiskDevice uDiskDevice) {
        if (TextUtils.isEmpty(uDiskDevice.getInternalPath())) {
            mCallback.noUDiskNotice();
            return;
        }
        mCallback.startLogExport();
        logExportControl.start(uDiskDevice, getLogTypePosition(mCurLogExportOSType));
    }

    /**
     * 日志清理
     */
    public void clickCleanBtn() {
        // 如果当前正处于导出日志中,则不进行日志清理
        if (checkIfIsLogCleaning() || checkIfIsLogExporting()) {
            return;
        }
        // 如果当前ApLog/BtLog/NetLog日志记录功能处于开启状态,需要暂时关闭且记录状态
        stopRecordingLogIfIsOpen();
        // 执行日志清理任务
        clearLog();
    }

    /**
     * 判断日志是否在导出中
     *
     * @return
     */
    private boolean checkIfIsLogExporting() {
        boolean res = logExportControl.isLogExporting();
        if (res) {
            mCallback.unSupportCleanIsLogExporting();
        }
        return res;
    }

    /**
     * 判断日志是否在清理中
     *
     * @return true 清理中 false 未在清理中
     */
    private boolean checkIfIsLogCleaning() {
        boolean res = SystemProperties.get(PROPERTY_LOG_CLEAN_ENABLE, "0").equals("1");
        SystemProperties.set(PROPERTY_LOG_CLEAN_ENABLE, "0");
        if (res) {
            mCallback.unSupportcleanIsLogCleaning();
        }
        return res;
    }

    public List<UDiskDevice> getUDiskDeviceList() {
        return logExportControl.getUDiskDeviceList();
    }


    /**
     * 改变日志等级
     *
     * @param position
     */
    public void changeRecordLevel(int position) {
        if (isUXOSType(mCurLogControlOSType)) {
            mCurLogControlOSLevel = level_array[position];
            SystemProperties.set(LEVEL_KEY, mCurLogControlOSLevel);
        } else if (isCurLogControlSocketConnect()) {
            //设置日志等级
            mCallback.startSetGuestOSLevel();
            setGuestOSRecording(0, position);
        } else {
            setSocketDataFail();
        }
    }

    /**
     * 根据日志等级返回第几个
     *
     * @return
     */
    public int getRecordLevelPosition() {
        if (isUXOSType(mCurLogControlOSType)) {
            mCurLogControlOSLevel = SystemProperties.get(LEVEL_KEY, "V");
            level_array = UXOS_LEVEL_ARRAY;
        } else {
            mCurLogControlOSLevel = (String) SPUtil.get(mContext, mCurLogControlOSType + "LEVEL", "D");
            level_array = GUEST_LEVEL_ARRAY;
        }
        return Arrays.asList(level_array).indexOf(mCurLogControlOSLevel);
    }

    /**
     * 日志清理时，临时关闭uxos日志
     */
    private void stopRecordingLogIfIsOpen() {
        reOpenApLog = false;
        reOpenBtLog = false;
        reOpenNetLog = false;

        if (isUXOSType(mCurLogCleanOSType)) {
            if (isUxOSIsRecording()) {
                reOpenApLog = true;
                if (isUXOSType(mCurLogControlOSType)) {
                    setCurOSRecording(false);
                } else {
                    SystemProperties.set(PROPERTY_LOG_AP_ENABLE, "0");
                }
            }
            if (isBtRecording()) {
                reOpenBtLog = true;
                setBtRecording(false);
                mCallback.changBtRecordState();
                // TODO 关闭蓝牙日志相关的系统属性
            }
            if (isNetRecording()) {
                reOpenNetLog = true;
                setBtRecording(false);
                mCallback.changNetRecordState(false);
            }
        }
    }

    /**
     * 关闭tcp日志开关
     */
    public void stopNetlogRecord() {
        if (isNetRecording()) {
            setNetRecording(false);
            mCallback.changNetRecordState(false);
        }
    }

    /**
     * 日志清理
     */
    private void clearLog() {
        // 开始清理日志,显示“清理中...”
        mCallback.startCleanLog();
        // 设置系统属性SystemProperties, 触发init进程执行日志清理脚本
        if (mCurLogCleanOSType.equals(UXOS_TYPE)) {
            cleanuxoxLog(PROPERTY_LOG_CLEAN_ENABLE, new String[]{LOG_PATH_AP, LOG_PATH_NET, LOG_PATH_ANR, LOG_PATH_TOMSTONES});
        } else if (mCurLogCleanOSType.equals(MCU_TYPE)) {
            cleanuxoxLog(PROPERTY_MCU_LOG_CLEAN_ENABLE, new String[]{MCU_LOG_PATH_AP});
        } else {
            cleanGuestOsLog();
        }
    }

    private void cleanuxoxLog(String propKey, String logDir[]) {
        SystemProperties.set(propKey, "1");
        // 设置计时器(总计时30秒,每0.5秒检查一次),不断检查系统属性,查看日志清理是否已经执行完成
        Log.d(TAG, "cleanuxoxLog: propKey=" + propKey);
        mLogCleanCountDownTimer = new CountDownTimer(1000 * 30, 500) {
            @Override
            public void onTick(long millisUntilFinished) {
                Log.d(TAG, "onTick: millisUntilFinished=" + millisUntilFinished);
                boolean finished = SystemProperties.get(propKey, "0").equals("0");
                if (finished) {
                    // 脚本执行完毕,系统属性已被修改
                    // 如果日志目录下全为空,顺利完成日志清理,显示“清理完成”
                    boolean b = Arrays.stream(logDir).allMatch(s -> dirIsEmpty(s));
                    if (b) {
                        finishLogCleaning(true);
                        // 如果日志目录不全为空,显示“清理失败”
                    } else {
                        finishLogCleaning(false);
                    }
                }
            }

            @Override
            public void onFinish() {
                Log.d(TAG, "cleanuxoxLog onFinish: ");
                // 脚本未能顺利执行完毕,或者超时仍未完成日志清理,显示”清理失败“
                finishLogCleaning(false);
                SystemProperties.set(propKey, "0");
            }
        };
        // 计时器启动
        mLogCleanCountDownTimer.start();
    }

    /**
     * 清除完成
     *
     * @param success
     */
    private void finishLogCleaning(boolean success) {
        mCallback.cleanLogFinish(success);
        // 关闭计时器
        if (mLogCleanCountDownTimer != null) {
            mLogCleanCountDownTimer.cancel();
            mLogCleanCountDownTimer = null;
        }
        // 如果日志清理前ApLog/BtLog/NetLog日志记录功能处于开启状态,需要重新打开对应的开关
        reStartRecordingLog();
    }

    private boolean isUXOSType(String OSType) {
        return TextUtils.equals(OSType, UXOS_TYPE);
    }

    /**
     * 设置日志开关系统日志类型
     *
     * @param position
     */
    public void setControlLogOSType(int position) {
        mCurLogControlOSType = LOGTYPES[position];
        SPUtil.put(mContext, SAVE_OPEN_LOG_TYPE_KEY, mCurLogControlOSType);
        if (isUXOSType(mCurLogControlOSType)) {
            level_array = UXOS_LEVEL_ARRAY;
            mCurControlOSStatus = SystemProperties.getInt(PROPERTY_LOG_AP_ENABLE, 0);
            mCallback.setUXOSLevelDataAndIndex(getRecordLevelPosition());
            mCallback.changApRecordState(isApRecording());
        } else {
            level_array = GUEST_LEVEL_ARRAY;
            connectSocket();
        }

    }

    /**
     * 设置日志清除日志类型
     *
     * @param position
     */
    public void setClearLogType(int position) {
        mCurLogCleanOSType = CLEAN_LOGTYPES[position];
        SPUtil.put(mContext, SAVE_CLEAR_LOG_TYPE_KEY, mCurLogCleanOSType);
        if (!mCurLogCleanOSType.equals(UXOS_TYPE) && !mCurLogCleanOSType.equals(MCU_TYPE)) {
            if (!SocketManager.get().isConnected(SocketManager.ServerOS.valueOf(mCurLogCleanOSType))) {
                SocketManager.get().connectServer(SocketManager.ServerOS.valueOf(mCurLogCleanOSType));
            }
        }
    }

    /**
     * 设置日志导出日志类型
     *
     * @param position 第几个
     */
    public void setLogOutType(int position) {
        mCurLogExportOSType = LOGTYPES[position];
        SPUtil.put(mContext, SAVE_EXPORT_LOG_TYPE_KEY, mCurLogExportOSType);
    }

    /**
     * UXOS是否开启日志
     *
     * @return true 开启 false 未开启
     */
    private boolean isUxOSIsRecording() {
        return SystemProperties.getInt(PROPERTY_LOG_AP_ENABLE, 0) == 1;
    }

    /**
     * 根据类型返回index
     *
     * @param type
     * @return
     */
    private int getLogTypePosition(String type) {
        return Arrays.asList(LOGTYPES).indexOf(type);
    }


    private int getCleanLogTypePosition(String type) {
        return Arrays.asList(CLEAN_LOGTYPES).indexOf(type);
    }

    /**
     * 日志清理完成后，如果之前日志在记录中，重新打开日志
     */
    private void reStartRecordingLog() {
        if (reOpenApLog) {
            if (isUXOSType(mCurLogControlOSType)) {
                setCurOSRecording(true);
                mCallback.changApRecordState(isApRecording());
            } else {
                SystemProperties.set(PROPERTY_LOG_AP_ENABLE, "1");
            }
        }
        if (reOpenBtLog) {
            setBtRecording(true);
            mCallback.changBtRecordState();
        }
        if (reOpenNetLog) {
            setBtRecording(true);
            mCallback.changNetRecordState(true);
        }
        reOpenApLog = false;
        reOpenBtLog = false;
        reOpenNetLog = false;
    }


    private boolean dirIsEmpty(String path) {
        File file = new File(path);
        return file.isDirectory() && file.listFiles().length <= 0;
    }


    public void release() {
        if (logExportControl != null) {
            logExportControl.release();
        }
        if (!isUXOSType(mCurLogControlOSType)) {
            if (isCurLogControlSocketConnect()) {
                SocketManager.get().disConnectServer(SocketManager.ServerOS.valueOf(mCurLogControlOSType));
            }
        }
    }

    /**
     * 连接失败处理
     */
    public void setSocketDataFail() {
        Log.d(TAG, "setSocketFail: ");
        mCurLogControlOSLevel = (String) SPUtil.get(mContext, mCurLogControlOSType + "LEVEL", "D");
        mCurControlOSStatus = (Integer) SPUtil.get(mContext, mCurLogControlOSType, 0);
        ThreadUtils.runOnUiThread(() -> {
            mCallback.socketConnectFail();
        });
    }
}
